tests := []struct {
name string
dryRun bool
+ isTTY bool
changes []safcm.FileChange
exp string
}{
{
"regular",
false,
+ false,
[]safcm.FileChange{
{
Path: "created: file",
`,
},
+ {
+ "regular (tty)",
+ false,
+ true,
+ []safcm.FileChange{
+ {
+ Path: "created: file",
+ Created: true,
+ New: safcm.FileChangeInfo{
+ Mode: 0644,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ },
+ {
+ Path: "created: link",
+ Created: true,
+ New: safcm.FileChangeInfo{
+ Mode: fs.ModeSymlink | 0777,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ },
+ {
+ Path: "type change: file -> dir",
+ Old: safcm.FileChangeInfo{
+ Mode: 0751,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ New: safcm.FileChangeInfo{
+ Mode: fs.ModeDir | 0751,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ DataDiff: `@@ -1,2 +1 @@
+-content
+
+`,
+ },
+ {
+ Path: "user change",
+ Old: safcm.FileChangeInfo{
+ Mode: 0755,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ New: safcm.FileChangeInfo{
+ Mode: 0755,
+ User: "user2",
+ Uid: 1001,
+ Group: "group",
+ Gid: 2000,
+ },
+ },
+ {
+ Path: "group change",
+ Old: safcm.FileChangeInfo{
+ Mode: 0755,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ New: safcm.FileChangeInfo{
+ Mode: 0755,
+ User: "user",
+ Uid: 1000,
+ Group: "group2",
+ Gid: 2001,
+ },
+ },
+ {
+ Path: "mode change",
+ Old: safcm.FileChangeInfo{
+ Mode: 0755,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ New: safcm.FileChangeInfo{
+ Mode: 0750,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ },
+ {
+ Path: "mode change (setuid)",
+ Old: safcm.FileChangeInfo{
+ Mode: 0755,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ New: safcm.FileChangeInfo{
+ Mode: 0755 | fs.ModeSetuid,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ },
+ {
+ Path: "content change",
+ Old: safcm.FileChangeInfo{
+ Mode: 0644,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ New: safcm.FileChangeInfo{
+ Mode: 0644,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ DataDiff: `@@ -1,2 +1,2 @@
+-old content
++content
+
+`,
+ },
+ {
+ Path: "multiple changes",
+ Old: safcm.FileChangeInfo{
+ Mode: 0644,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ New: safcm.FileChangeInfo{
+ Mode: fs.ModeDir | 0755,
+ User: "user2",
+ Uid: 1001,
+ Group: "group2",
+ Gid: 2001,
+ },
+ DataDiff: `@@ -1,2 +1 @@
+-content
+
+`,
+ },
+ },
+ "changed 9 file(s):\n\x1b[36m\"created: file\"\x1b[0m: \x1b[32mcreated\x1b[0m, file, user(1000) group(2000), 0644\n\x1b[36m\"created: link\"\x1b[0m: \x1b[32mcreated\x1b[0m, symlink, user(1000) group(2000), 0777\n\x1b[36m\"type change: file -> dir\"\x1b[0m: file -> dir\n @@ -1,2 +1 @@\n\x1b[31m -content\x1b[0m\n \n\x1b[36m\"user change\"\x1b[0m: user(1000) group(2000) -> user2(1001) group(2000)\n\x1b[36m\"group change\"\x1b[0m: user(1000) group(2000) -> user(1000) group2(2001)\n\x1b[36m\"mode change\"\x1b[0m: 0755 -> 0750\n\x1b[36m\"mode change (setuid)\"\x1b[0m: 0755 -> 04755\n\x1b[36m\"content change\"\x1b[0m:\n @@ -1,2 +1,2 @@\n\x1b[31m -old content\x1b[0m\n\x1b[32m +content\x1b[0m\n \n\x1b[36m\"multiple changes\"\x1b[0m: file -> dir, user(1000) group(2000) -> user2(1001) group2(2001), 0644 -> 0755\n @@ -1,2 +1 @@\n\x1b[31m -content\x1b[0m\n \n",
+ },
+
{
"dry-run",
true,
+ false,
[]safcm.FileChange{
{
Path: "file",
`,
},
+ {
+ "dry-run (tty)",
+ true,
+ true,
+ []safcm.FileChange{
+ {
+ Path: "file",
+ Created: true,
+ New: safcm.FileChangeInfo{
+ Mode: 0644,
+ User: "user",
+ Uid: 1000,
+ Group: "group",
+ Gid: 2000,
+ },
+ },
+ },
+ "changed 1 file(s): (dry-run)\n\x1B[36m\"file\"\x1B[0m: \x1B[32mcreated\x1B[0m, file, user(1000) group(2000), 0644\n",
+ },
+
{
"escaping",
false,
+ false,
[]safcm.FileChange{
{
Path: "\x00",
\ No newline at end of file
`,
},
+
+ {
+ "escaping (tty)",
+ false,
+ true,
+ []safcm.FileChange{
+ {
+ Path: "\x00",
+ Created: true,
+ New: safcm.FileChangeInfo{
+ Mode: 0xFFFFFFFF,
+ User: "\x01",
+ Uid: -1,
+ Group: "\x02",
+ Gid: -2,
+ },
+ DataDiff: "\x03",
+ },
+ {
+ Path: "\x00",
+ Old: safcm.FileChangeInfo{
+ Mode: 0x00000000,
+ User: "\x01",
+ Uid: -1,
+ Group: "\x02",
+ Gid: -2,
+ },
+ New: safcm.FileChangeInfo{
+ Mode: 0xFFFFFFFF,
+ User: "\x03",
+ Uid: -3,
+ Group: "\x04",
+ Gid: -4,
+ },
+ DataDiff: "\x05",
+ },
+ },
+ "changed 2 file(s):\n\x1b[36m\"\\x00\"\x1b[0m: \x1b[32mcreated\x1b[0m, invalid type dLDpSc?---------, \\x01(-1) \\x02(-2), 07777\n \\x03\n \\ No newline at end of file\n\x1b[36m\"\\x00\"\x1b[0m: file -> invalid type dLDpSc?---------, \\x01(-1) \\x02(-2) -> \\x03(-3) \\x04(-4), 0 -> 07777\n \\x05\n \\ No newline at end of file\n",
+ },
}
for _, tc := range tests {
config: &config.Config{
DryRun: tc.dryRun,
},
+ isTTY: tc.isTTY,
}
res := s.formatFileChanges(tc.changes)
tests := []struct {
name string
dryRun bool
+ isTTY bool
changes []safcm.PackageChange
exp string
}{
{
"regular",
false,
+ false,
[]safcm.PackageChange{
{
Name: "package-one",
`,
},
+ {
+ "regular (tty)",
+ false,
+ true,
+ []safcm.PackageChange{
+ {
+ Name: "package-one",
+ },
+ {
+ Name: "package-two",
+ },
+ },
+ "installed 2 package(s):\n\x1b[36m\"package-one\"\x1b[0m\n\x1b[36m\"package-two\"\x1b[0m\n",
+ },
+
{
"dry-run",
true,
+ false,
[]safcm.PackageChange{
{
Name: "package-one",
`,
},
+ {
+ "dry-run (tty)",
+ true,
+ true,
+ []safcm.PackageChange{
+ {
+ Name: "package-one",
+ },
+ {
+ Name: "package-two",
+ },
+ },
+ "installed 2 package(s): (dry-run)\n\x1b[36m\"package-one\"\x1b[0m\n\x1b[36m\"package-two\"\x1b[0m\n",
+ },
+
{
"escaping",
false,
+ false,
[]safcm.PackageChange{
{
Name: "\x00",
"\x00"
`,
},
+
+ {
+ "escaping (tty)",
+ false,
+ true,
+ []safcm.PackageChange{
+ {
+ Name: "\x00",
+ },
+ },
+ "installed 1 package(s):\n\x1b[36m\"\\x00\"\x1b[0m\n",
+ },
}
for _, tc := range tests {
config: &config.Config{
DryRun: tc.dryRun,
},
+ isTTY: tc.isTTY,
}
res := s.formatPackageChanges(tc.changes)
tests := []struct {
name string
dryRun bool
+ isTTY bool
changes []safcm.ServiceChange
exp string
}{
{
"regular",
false,
+ false,
[]safcm.ServiceChange{
{
Name: "service-one",
`,
},
+ {
+ "regular (tty)",
+ false,
+ true,
+ []safcm.ServiceChange{
+ {
+ Name: "service-one",
+ Started: true,
+ },
+ {
+ Name: "service-two",
+ Enabled: true,
+ },
+ {
+ Name: "service-three",
+ Started: true,
+ Enabled: true,
+ },
+ },
+ "modified 3 service(s):\n\x1b[36m\"service-one\"\x1b[0m: started\n\x1b[36m\"service-two\"\x1b[0m: enabled\n\x1b[36m\"service-three\"\x1b[0m: started, enabled\n",
+ },
+
{
"dry-run",
true,
+ false,
[]safcm.ServiceChange{
{
Name: "service-one",
`,
},
+ {
+ "dry-run (tty)",
+ true,
+ true,
+ []safcm.ServiceChange{
+ {
+ Name: "service-one",
+ Started: true,
+ },
+ {
+ Name: "service-two",
+ Enabled: true,
+ },
+ {
+ Name: "service-three",
+ Started: true,
+ Enabled: true,
+ },
+ },
+ "modified 3 service(s): (dry-run)\n\x1b[36m\"service-one\"\x1b[0m: started\n\x1b[36m\"service-two\"\x1b[0m: enabled\n\x1b[36m\"service-three\"\x1b[0m: started, enabled\n",
+ },
+
{
"escaping",
false,
+ false,
[]safcm.ServiceChange{
{
Name: "\x00",
"\x01": started, enabled
`,
},
+
+ {
+ "escaping (tty)",
+ false,
+ true,
+ []safcm.ServiceChange{
+ {
+ Name: "\x00",
+ },
+ {
+ Name: "\x01",
+ Started: true,
+ Enabled: true,
+ },
+ },
+ "modified 2 service(s):\n\x1b[36m\"\\x00\"\x1b[0m: \n\x1b[36m\"\\x01\"\x1b[0m: started, enabled\n",
+ },
}
for _, tc := range tests {
config: &config.Config{
DryRun: tc.dryRun,
},
+ isTTY: tc.isTTY,
}
res := s.formatServiceChanges(tc.changes)
name string
dryRun bool
quiet bool
+ isTTY bool
changes []safcm.CommandChange
exp string
}{
"regular",
false,
false,
+ false,
[]safcm.CommandChange{
{
Command: "fake command",
`,
},
+ {
+ "regular (tty)",
+ false,
+ false,
+ true,
+ []safcm.CommandChange{
+ {
+ Command: "fake command",
+ Output: "fake output",
+ },
+ {
+ Command: "fake command with no output",
+ },
+ {
+ Command: "fake command with newline",
+ Output: "fake output\n",
+ },
+ {
+ Command: "fake command with more output",
+ Output: "fake out\nfake put\nfake\n",
+ },
+ {
+ Command: "fake failed command",
+ Output: "fake output",
+ Error: "fake error",
+ },
+ },
+ "executed 5 command(s):\n\x1b[36m\"fake command\"\x1b[0m:\n > fake output\n > \\ No newline at end of file\n\x1b[36m\"fake command with no output\"\x1b[0m\n\x1b[36m\"fake command with newline\"\x1b[0m:\n > fake output\n\x1b[36m\"fake command with more output\"\x1b[0m:\n > fake out\n > fake put\n > fake\n\x1b[36m\"fake failed command\"\x1b[0m, failed: \"fake error\":\n > fake output\n > \\ No newline at end of file\n",
+ },
+
{
"dry-run",
true,
false,
+ false,
[]safcm.CommandChange{
{
Command: "fake command",
`,
},
+ {
+ "dry-run (tty)",
+ true,
+ false,
+ true,
+ []safcm.CommandChange{
+ {
+ Command: "fake command",
+ Output: "fake output",
+ },
+ },
+ "executed 1 command(s): (dry-run)\n\x1b[36m\"fake command\"\x1b[0m:\n > fake output\n > \\ No newline at end of file\n",
+ },
+
{
"quiet",
false,
true,
+ false,
[]safcm.CommandChange{
{
Command: "fake command",
`,
},
+ {
+ "quiet (tty)",
+ false,
+ true,
+ true,
+ []safcm.CommandChange{
+ {
+ Command: "fake command",
+ Output: "fake output",
+ },
+ {
+ Command: "fake command with no output",
+ },
+ {
+ Command: "fake command with newline",
+ Output: "fake output\n",
+ },
+ {
+ Command: "fake command with more output",
+ Output: "fake out\nfake put\nfake\n",
+ },
+ {
+ Command: "fake failed command",
+ Output: "fake output",
+ Error: "fake error",
+ },
+ },
+ "executed 5 command(s), 1 with no output:\n\x1b[36m\"fake command\"\x1b[0m:\n > fake output\n > \\ No newline at end of file\n\x1b[36m\"fake command with newline\"\x1b[0m:\n > fake output\n\x1b[36m\"fake command with more output\"\x1b[0m:\n > fake out\n > fake put\n > fake\n\x1b[36m\"fake failed command\"\x1b[0m, failed: \"fake error\":\n > fake output\n > \\ No newline at end of file\n",
+ },
+
{
"quiet (only quiet commands)",
false,
true,
+ false,
[]safcm.CommandChange{
{
Command: "fake command with no output",
"quiet (quiet with errors)",
false,
true,
+ false,
[]safcm.CommandChange{
{
Command: "fake command with no output but error",
"quiet & dry-run",
true,
true,
+ false,
[]safcm.CommandChange{
{
Command: "fake command",
"escaping",
false,
false,
+ false,
[]safcm.CommandChange{
{
Command: "\x00",
> \ No newline at end of file
`,
},
+
+ {
+ "escaping (tty)",
+ false,
+ false,
+ true,
+ []safcm.CommandChange{
+ {
+ Command: "\x00",
+ Trigger: "\x01",
+ Output: "\x02",
+ Error: "\x03",
+ },
+ },
+ "executed 1 command(s):\n\x1b[36m\"\\x00\"\x1b[0m, trigger for \"\\x01\", failed: \"\\x03\":\n > \x1b[35m\\x02\x1b[0m\n > \\ No newline at end of file\n",
+ },
}
for _, tc := range tests {
DryRun: tc.dryRun,
Quiet: tc.quiet,
},
+ isTTY: tc.isTTY,
}
res := s.formatCommandChanges(tc.changes)