<commit_before>package main

import (
	"bufio"
	"errors"
	"fmt"
	imgclient "github.com/Symantec/Dominator/imageserver/client"
	"github.com/Symantec/Dominator/lib/constants"
	"github.com/Symantec/Dominator/lib/filesystem"
	"github.com/Symantec/Dominator/lib/objectclient"
	"github.com/Symantec/Dominator/lib/srpc"
	"github.com/Symantec/Dominator/proto/imageserver"
	"github.com/Symantec/Dominator/proto/sub"
	subclient "github.com/Symantec/Dominator/sub/client"
	"io/ioutil"
	"net/rpc"
	"os"
	"os/exec"
)

func diffImageVImageSubcommand(imageClient *rpc.Client,
	imageSClient *srpc.Client, objectClient *objectclient.ObjectClient,
	args []string) {
	err := diffImageVImage(imageSClient, args[0], args[1], args[2])
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error diffing images\t%s\n", err)
		os.Exit(1)
	}
	os.Exit(0)
}

func diffImageVImage(client *srpc.Client, tool, limage, rimage string) error {
	lfs, err := getImage(client, limage)
	if err != nil {
		return err
	}
	rfs, err := getImage(client, rimage)
	if err != nil {
		return err
	}
	return diffImages(tool, lfs, rfs)
}

func diffImageVSubSubcommand(imageClient *rpc.Client, imageSClient *srpc.Client,
	objectClient *objectclient.ObjectClient, args []string) {
	err := diffImageVSub(imageSClient, args[0], args[1], args[2])
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error diffing images\t%s\n", err)
		os.Exit(1)
	}
	os.Exit(0)
}

func diffImageVSub(client *srpc.Client, tool, image, sub string) error {
	lfs, err := getImage(client, image)
	if err != nil {
		return err
	}
	rfs, err := pollImage(sub)
	if err != nil {
		return err
	}
	return diffImages(tool, lfs, rfs)
}

func diffSubVImageSubcommand(imageClient *rpc.Client, imageSClient *srpc.Client,
	objectClient *objectclient.ObjectClient, args []string) {
	err := diffSubVImage(imageSClient, args[0], args[1], args[2])
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error diffing images\t%s\n", err)
		os.Exit(1)
	}
	os.Exit(0)
}

func diffSubVImage(client *srpc.Client, tool, sub, image string) error {
	lfs, err := pollImage(sub)
	if err != nil {
		return err
	}
	rfs, err := getImage(client, image)
	if err != nil {
		return err
	}
	return diffImages(tool, lfs, rfs)
}

func diffSubVSubSubcommand(imageClient *rpc.Client, imageSClient *srpc.Client,
	objectClient *objectclient.ObjectClient, args []string) {
	err := diffSubVSub(args[0], args[1], args[2])
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error diffing images\t%s\n", err)
		os.Exit(1)
	}
	os.Exit(0)
}

func diffSubVSub(tool, subl, subr string) error {
	lfs, err := pollImage(subl)
	if err != nil {
		return err
	}
	rfs, err := pollImage(subr)
	if err != nil {
		return err
	}
	return diffImages(tool, lfs, rfs)
}

func getImage(client *srpc.Client, name string) (
	*filesystem.FileSystem, error) {
	var request imageserver.GetImageRequest
	request.ImageName = name
	var reply imageserver.GetImageResponse
	if err := imgclient.CallGetImage(client, request, &reply); err != nil {
		return nil, err
	}
	if reply.Image == nil {
		return nil, errors.New(name + ": not found")
	}
	reply.Image.FileSystem.RebuildInodePointers()
	return reply.Image.FileSystem, nil
}

func pollImage(name string) (*filesystem.FileSystem, error) {
	clientName := fmt.Sprintf("%s:%d", name, constants.SubPortNumber)
	srpcClient, err := srpc.DialHTTP("tcp", clientName)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Error dialing %s", err))
	}
	defer srpcClient.Close()
	var request sub.PollRequest
	var reply sub.PollResponse
	if err = subclient.CallPoll(srpcClient, request, &reply); err != nil {
		return nil, err
	}
	if reply.FileSystem == nil {
		return nil, errors.New("no poll data")
	}
	reply.FileSystem.RebuildInodePointers()
	return reply.FileSystem, nil
}

func diffImages(tool string, lfs, rfs *filesystem.FileSystem) error {
	lname, err := writeImage(lfs)
	defer os.Remove(lname)
	if err != nil {
		return err
	}
	rname, err := writeImage(rfs)
	defer os.Remove(rname)
	if err != nil {
		return err
	}
	cmd := exec.Command(tool, lname, rname)
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func writeImage(fs *filesystem.FileSystem) (string, error) {
	file, err := ioutil.TempFile("", "imagetool")
	if err != nil {
		return "", err
	}
	defer file.Close()
	writer := bufio.NewWriter(file)
	defer writer.Flush()
	return file.Name(), fs.List(writer)
}
<commit_msg>Refactored imagetool diff?? subcommands to shrink code.<commit_after>package main

import (
	"bufio"
	"errors"
	"fmt"
	imgclient "github.com/Symantec/Dominator/imageserver/client"
	"github.com/Symantec/Dominator/lib/constants"
	"github.com/Symantec/Dominator/lib/filesystem"
	"github.com/Symantec/Dominator/lib/objectclient"
	"github.com/Symantec/Dominator/lib/srpc"
	"github.com/Symantec/Dominator/proto/imageserver"
	"github.com/Symantec/Dominator/proto/sub"
	subclient "github.com/Symantec/Dominator/sub/client"
	"io/ioutil"
	"net/rpc"
	"os"
	"os/exec"
)

func diffImageVImageSubcommand(imageClient *rpc.Client,
	imageSClient *srpc.Client, objectClient *objectclient.ObjectClient,
	args []string) {
	commonDiffSubcommand(imageSClient, args[0],
		args[1], getImage, args[2], getImage)
}

func diffImageVSubSubcommand(imageClient *rpc.Client, imageSClient *srpc.Client,
	objectClient *objectclient.ObjectClient, args []string) {
	commonDiffSubcommand(imageSClient, args[0],
		args[1], getImage, args[2], pollImage)
}

func diffSubVImageSubcommand(imageClient *rpc.Client, imageSClient *srpc.Client,
	objectClient *objectclient.ObjectClient, args []string) {
	commonDiffSubcommand(imageSClient, args[0],
		args[1], pollImage, args[2], getImage)
}

func diffSubVSubSubcommand(imageClient *rpc.Client, imageSClient *srpc.Client,
	objectClient *objectclient.ObjectClient, args []string) {
	commonDiffSubcommand(imageSClient, args[0],
		args[1], pollImage, args[2], pollImage)
}

func commonDiffSubcommand(client *srpc.Client, tool string,
	lName string, lGetFunc func(client *srpc.Client, name string) (
		*filesystem.FileSystem, error),
	rName string, rGetFunc func(client *srpc.Client, name string) (
		*filesystem.FileSystem, error)) {
	lfs, err := lGetFunc(client, lName)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error getting left image\t%s\n", err)
		os.Exit(1)
	}
	rfs, err := rGetFunc(client, rName)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error getting right image\t%s\n", err)
		os.Exit(1)
	}
	err = diffImages(tool, lfs, rfs)
	if err != nil {
		fmt.Fprintf(os.Stderr, "Error diffing images\t%s\n", err)
		os.Exit(1)
	}
	os.Exit(0)
}

func getImage(client *srpc.Client, name string) (
	*filesystem.FileSystem, error) {
	var request imageserver.GetImageRequest
	request.ImageName = name
	var reply imageserver.GetImageResponse
	if err := imgclient.CallGetImage(client, request, &reply); err != nil {
		return nil, err
	}
	if reply.Image == nil {
		return nil, errors.New(name + ": not found")
	}
	reply.Image.FileSystem.RebuildInodePointers()
	return reply.Image.FileSystem, nil
}

func pollImage(client *srpc.Client, name string) (
	*filesystem.FileSystem, error) {
	clientName := fmt.Sprintf("%s:%d", name, constants.SubPortNumber)
	srpcClient, err := srpc.DialHTTP("tcp", clientName)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("Error dialing %s", err))
	}
	defer srpcClient.Close()
	var request sub.PollRequest
	var reply sub.PollResponse
	if err = subclient.CallPoll(srpcClient, request, &reply); err != nil {
		return nil, err
	}
	if reply.FileSystem == nil {
		return nil, errors.New("no poll data")
	}
	reply.FileSystem.RebuildInodePointers()
	return reply.FileSystem, nil
}

func diffImages(tool string, lfs, rfs *filesystem.FileSystem) error {
	lname, err := writeImage(lfs)
	defer os.Remove(lname)
	if err != nil {
		return err
	}
	rname, err := writeImage(rfs)
	defer os.Remove(rname)
	if err != nil {
		return err
	}
	cmd := exec.Command(tool, lname, rname)
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func writeImage(fs *filesystem.FileSystem) (string, error) {
	file, err := ioutil.TempFile("", "imagetool")
	if err != nil {
		return "", err
	}
	defer file.Close()
	writer := bufio.NewWriter(file)
	defer writer.Flush()
	return file.Name(), fs.List(writer)
}

{'fraction_non_alphanumeric': 0.1406769230769231, 'fraction_numerical': 0.004430769230769231, 'mean_word_length': 4.796005706134094, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7457491', 'n_tokens_mistral': 3097, 'n_tokens_neox': 3056, 'n_words': 676}