github.com/stackb/rules_proto@v0.0.0-20240221195024-5428336c51f1/cmd/gencopy/gencopy_test.go (about)

     1  // gencopy is a utility program that copies bazel outputs back into the
     2  // workspace source tree.  Ideally, you don't have any generated files committed
     3  // to VCS, but sometimes you do.
     4  package main
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	"github.com/bazelbuild/bazel-gazelle/testtools"
    12  	"github.com/google/go-cmp/cmp"
    13  )
    14  
    15  func TestParseFileMode(t *testing.T) {
    16  	for name, tc := range map[string]struct {
    17  		in   string
    18  		want os.FileMode
    19  	}{
    20  		"ModePerm": {
    21  			in:   "0777",
    22  			want: os.FileMode(os.ModePerm),
    23  		},
    24  		"0644": {
    25  			in:   "0644",
    26  			want: os.FileMode(0o644),
    27  		},
    28  		"ModeSetgid": {
    29  			in:   "020000000",
    30  			want: os.FileMode(os.ModeSetgid),
    31  		},
    32  	} {
    33  		t.Run(name, func(t *testing.T) {
    34  			mode, err := parseFileMode(tc.in)
    35  			if err != nil {
    36  				t.Fatal(err)
    37  			}
    38  			got := os.FileMode(mode)
    39  			if tc.want != got {
    40  				t.Errorf("want %#o, got %#o", tc.want, got)
    41  			}
    42  		})
    43  	}
    44  }
    45  
    46  func TestMakePkgSrcDstPair(t *testing.T) {
    47  	for name, tc := range map[string]struct {
    48  		cfg      Config
    49  		pkg      PackageConfig
    50  		src, dst string
    51  		want     SrcDst
    52  	}{
    53  		"degenerate": {},
    54  		"WorkspaceRootDirectory": {
    55  			cfg:  Config{WorkspaceRootDirectory: "/home"},
    56  			src:  "file.txt",
    57  			dst:  "file.txt",
    58  			want: SrcDst{Src: "file.txt", Dst: "/home/file.txt"},
    59  		},
    60  		"WorkspaceSubDirectory": {
    61  			cfg:  Config{WorkspaceRootDirectory: "/home"},
    62  			src:  "subdir/file.txt",
    63  			dst:  "subdir/file.txt",
    64  			want: SrcDst{Src: "subdir/file.txt", Dst: "/home/subdir/file.txt"},
    65  		},
    66  		"TargetWorkspaceRoot": {
    67  			cfg:  Config{WorkspaceRootDirectory: "/home"},
    68  			pkg:  PackageConfig{TargetWorkspaceRoot: "external/foo"},
    69  			src:  "../foo/file.txt",
    70  			dst:  "file.txt",
    71  			want: SrcDst{Src: "external/foo/file.txt", Dst: "/home/external/foo/file.txt"},
    72  		},
    73  	} {
    74  		t.Run(name, func(t *testing.T) {
    75  			got := makePkgSrcDstPair(&tc.cfg, &tc.pkg, tc.src, tc.dst)
    76  
    77  			if diff := cmp.Diff(tc.want, *got); diff != "" {
    78  				t.Errorf("(-want +got):\n%s", diff)
    79  			}
    80  		})
    81  	}
    82  }
    83  
    84  func TestRunPkg(t *testing.T) {
    85  	for name, tc := range map[string]struct {
    86  		cfg         Config
    87  		files, want []testtools.FileSpec
    88  	}{
    89  		"degenerate": {},
    90  		"simple": {
    91  			// {"extension":"","fileMode":"0644","mode":"update","packageConfigs":[{"generatedFiles":["api/v1/v1_pb2.py"],"sourceFiles":["api/v1/v1_pb2.py"],"targetLabel":"@//api/v1:api_v1_python_compiled_sources","targetPackage":"api/v1","targetWorkspaceRoot":""}],"updateTargetLabelName":"api_v1_python_compiled_sources.update"}
    92  			cfg: Config{
    93  				Extension:              "",
    94  				FileMode:               "0644",
    95  				Mode:                   "update",
    96  				WorkspaceRootDirectory: "workspace",
    97  				UpdateTargetLabelName:  "api_v1_python_compiled_sources.update",
    98  				PackageConfigs: []*PackageConfig{
    99  					{
   100  						GeneratedFiles:      []string{"api/v1/v1_pb2.py"},
   101  						SourceFiles:         []string{"api/v1/v1_pb2.py"},
   102  						TargetLabel:         "@//api/v1:api_v1_python_compiled_sources",
   103  						TargetPackage:       "api/v1",
   104  						TargetWorkspaceRoot: "gen",
   105  					},
   106  				},
   107  			},
   108  			files: []testtools.FileSpec{
   109  				{
   110  					Path:    "workspace/api/v1/v1_pb2.py",
   111  					Content: "# generated file api/v1/v1_pb2.py",
   112  				},
   113  			},
   114  			want: []testtools.FileSpec{
   115  				{
   116  					Path:    "api/v1/v1_pb2.py",
   117  					Content: "# generated file api/v1/v1_pb2.py",
   118  				},
   119  			},
   120  		},
   121  	} {
   122  		t.Run(name, func(t *testing.T) {
   123  			dir, cleanup := testtools.CreateFiles(t, tc.files)
   124  			defer cleanup()
   125  
   126  			if err := os.Chdir(dir); err != nil {
   127  				t.Fatal(err)
   128  			}
   129  			listFiles(t, ".")
   130  			if err := run(&tc.cfg, t.Logf); err != nil {
   131  				t.Fatal(err)
   132  			}
   133  
   134  			testtools.CheckFiles(t, dir, tc.want)
   135  		})
   136  	}
   137  }
   138  
   139  // listFiles - convenience debugging function to log the files under a given dir
   140  func listFiles(t *testing.T, dir string) error {
   141  	return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
   142  		if err != nil {
   143  			t.Logf("%v\n", err)
   144  			return err
   145  		}
   146  		if info.Mode()&os.ModeSymlink > 0 {
   147  			link, err := os.Readlink(path)
   148  			if err != nil {
   149  				return err
   150  			}
   151  			t.Logf("%s -> %s", path, link)
   152  			return nil
   153  		}
   154  
   155  		t.Log(path)
   156  		return nil
   157  	})
   158  }