func convert(vulns <-chan Convertible) error {
	defer stats.TrackTime("convert.time", time.Now(), time.Second)
	var feed nvd.NVDCVEFeedJSON10
	for vuln := range vulns {
		converted, err := vuln.Convert()
		if err != nil {
			flog.Errorf("error while converting vuln: %v", err)
			continue
		}
		feed.CVEItems = append(feed.CVEItems, converted)
	}
	if err := json.NewEncoder(os.Stdout).Encode(feed); err != nil {
		return fmt.Errorf("couldn't write NVD feed: %v", err)
	}
	return nil
}
getNVDFeed will convert the vulns in channel to NVD Feed
package runner
import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"os"
	"sync"
	"time"
	"github.com/facebookincubator/flog"
	nvd "github.com/facebookincubator/nvdtools/cvefeed/nvd/schema"
	"github.com/facebookincubator/nvdtools/providers/lib/client"
	"github.com/facebookincubator/nvdtools/stats"
)
type Convertible interface {
	ID() string
	Convert() (*nvd.NVDCVEFeedJSON10DefCVEItem, error)
}
type Read func(io.Reader, chan Convertible) error
type FetchSince func(ctx context.Context, c client.Client, baseURL string, since int64) (<-chan Convertible, error)
type Runner struct {
	Config
	FetchSince
	Read
}
func (r *Runner) Run() error {
	r.Config.addFlags()
	stats.AddFlags()
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [flags]\n", os.Args[0])
		flag.PrintDefaults()
		os.Exit(1)
	}
	flag.Parse()
	defer func(startTime time.Time) {
		stats.TrackTime("run.time", startTime, time.Second)
		stats.WriteAndLogError()
	}(time.Now())
	if err := r.Config.validate(); err != nil {
		return fmt.Errorf("config is invalid: %v", err)
	}
	var vulns <-chan Convertible
	var err error
	if r.Config.download {
		vulns, err = r.downloadVulnerabilities(context.Background())
	} else {
		vulns, err = r.readVulnerabilities()
	}
	if err != nil {
		return fmt.Errorf("couldn't get vulnerabilities: %v", err)
	}
	if r.Config.convert {
		if err := convert(vulns); err != nil {
			return fmt.Errorf("failed to convert vulns: %v", err)
		}
		return nil
	}
	m := make(map[string]Convertible)
	for v := range vulns {
		m[v.ID()] = v
	}
	if err := json.NewEncoder(os.Stdout).Encode(m); err != nil {
		return fmt.Errorf("couldn't write vulnerabilities: %v", err)
	}
	return nil
}
func (r *Runner) downloadVulnerabilities(ctx context.Context) (<-chan Convertible, error) {
	c := client.Default()
	c = r.Config.ClientConfig.Configure(c)
	return r.FetchSince(ctx, c, r.Config.BaseURL, int64(r.Config.downloadSince))
}
func (r *Runner) readVulnerabilities() (<-chan Convertible, error) {
	vulns := make(chan Convertible)
	if flag.NArg() == 0 {
		go func() {
			defer close(vulns)
			if err := r.Read(os.Stdin, vulns); err != nil {
				flog.Errorf("error while reading from stdin: %v", err)
			}
		}()
		return vulns, nil
	}
	wg := sync.WaitGroup{}
	for _, filename := range flag.Args() {
		wg.Add(1)
		go func(filename string) {
			defer wg.Done()
			file, err := os.Open(filename)
			if err != nil {
				flog.Errorf("couldn't open file %q: %v", filename, err)
				return
			}
			defer file.Close()
			if err := r.Read(file, vulns); err != nil {
				flog.Errorf("error while reading from file %q: %v", filename, err)
			}
		}(filename)
	}
	go func() {
		defer close(vulns)
		wg.Wait()
	}()
	return vulns, nil
}