func (c *CheckCommand) Run(input concourse.CheckRequest) (concourse.CheckResponse, error) {
	c.logger.Info("Received input, starting Check CMD run")

	err := c.removeExistingLogFiles()
	if err != nil {
		return nil, err
	}

	releaseType := input.Source.ReleaseType

	err = c.validateReleaseType(releaseType)
	if err != nil {
		return nil, err
	}

	productSlug := input.Source.ProductSlug

	c.logger.Info("Getting all releases")
	releases, err := c.pivnetClient.ReleasesForProductSlug(productSlug)
	if err != nil {
		return nil, err
	}

	if releaseType != "" {
		c.logger.Info(fmt.Sprintf("Filtering all releases by release type: '%s'", releaseType))
		releases, err = c.filter.ReleasesByReleaseType(
			releases,
			pivnet.ReleaseType(releaseType),
		)
		if err != nil {
			return nil, err
		}
	}

	version := input.Source.ProductVersion
	if version != "" {
		c.logger.Info(fmt.Sprintf("Filtering all releases by product version: '%s'", version))
		releases, err = c.filter.ReleasesByVersion(releases, version)
		if err != nil {
			return nil, err
		}
	}

	if input.Source.SortBy == concourse.SortBySemver {
		c.logger.Info("Sorting all releases by semver")
		releases, err = c.semverSorter.SortBySemver(releases)
		if err != nil {
			return nil, err
		}
	}

	vs, err := releaseVersions(releases)
	if err != nil {
		// Untested because versions.CombineVersionAndFingerprint cannot be forced to return an error.
		return concourse.CheckResponse{}, err
	}

	if len(vs) == 0 {
		return concourse.CheckResponse{}, nil
	}

	c.logger.Info("Gathering new versions")

	newVersions, err := versions.Since(vs, input.Version.ProductVersion)
	if err != nil {
		// Untested because versions.Since cannot be forced to return an error.
		return nil, err
	}

	reversedVersions, err := versions.Reverse(newVersions)
	if err != nil {
		// Untested because versions.Reverse cannot be forced to return an error.
		return nil, err
	}

	c.logger.Info(fmt.Sprintf("New versions: %v", reversedVersions))

	var out concourse.CheckResponse
	for _, v := range reversedVersions {
		out = append(out, concourse.Version{ProductVersion: v})
	}

	if len(out) == 0 {
		out = append(out, concourse.Version{ProductVersion: vs[0]})
	}

	c.logger.Info("Finishing check and returning ouput")

	return out, nil
}
func (rc ReleaseCreator) Create() (pivnet.Release, error) {
	version := rc.metadata.Release.Version

	if rc.source.SortBy == concourse.SortBySemver {
		v, err := rc.semverConverter.ToValidSemver(version)
		if err != nil {
			return pivnet.Release{}, err
		}
		rc.logger.Info(fmt.Sprintf("Successfully parsed semver as: '%s'", v.String()))
	}

	if rc.source.ProductVersion != "" {
		rc.logger.Info(fmt.Sprintf(
			"Validating product version: '%s' against regex: '%s'",
			version,
			rc.source.ProductVersion,
		))

		match, err := regexp.MatchString(rc.source.ProductVersion, version)
		if err != nil {
			return pivnet.Release{}, err
		}

		if !match {
			return pivnet.Release{}, fmt.Errorf(
				"provided product version: '%s' does not match regex in source: '%s'",
				version,
				rc.source.ProductVersion,
			)
		}
	}

	eulaSlug := rc.metadata.Release.EULASlug

	rc.logger.Info(fmt.Sprintf("Validating EULA: '%s'", eulaSlug))

	eulas, err := rc.pivnet.EULAs()
	if err != nil {
		return pivnet.Release{}, err
	}

	eulaSlugs := make([]string, len(eulas))
	for i, e := range eulas {
		eulaSlugs[i] = e.Slug
	}

	var containsSlug bool
	for _, slug := range eulaSlugs {
		if eulaSlug == slug {
			containsSlug = true
			break
		}
	}

	if !containsSlug {
		eulaSlugsPrintable := fmt.Sprintf("['%s']", strings.Join(eulaSlugs, "', '"))
		return pivnet.Release{}, fmt.Errorf(
			"provided EULA slug: '%s' must be one of: %s",
			eulaSlug,
			eulaSlugsPrintable,
		)
	}

	releaseType := pivnet.ReleaseType(rc.metadata.Release.ReleaseType)

	rc.logger.Info(fmt.Sprintf("Validating release type: '%s'", releaseType))

	releaseTypes, err := rc.pivnet.ReleaseTypes()
	if err != nil {
		return pivnet.Release{}, err
	}

	releaseTypesAsStrings := make([]string, len(releaseTypes))
	for i, r := range releaseTypes {
		releaseTypesAsStrings[i] = string(r)
	}

	var containsReleaseType bool
	for _, t := range releaseTypes {
		if releaseType == t {
			containsReleaseType = true
			break
		}
	}

	if !containsReleaseType {
		releaseTypesPrintable := fmt.Sprintf(
			"['%s']",
			strings.Join(releaseTypesAsStrings, "', '"),
		)
		return pivnet.Release{}, fmt.Errorf(
			"provided release type: '%s' must be one of: %s",
			releaseType,
			releaseTypesPrintable,
		)
	}

	if pivnet.ReleaseType(rc.source.ReleaseType) != "" &&
		pivnet.ReleaseType(rc.source.ReleaseType) != releaseType {
		return pivnet.Release{}, fmt.Errorf(
			"provided release type: '%s' must match '%s' from source configuration",
			releaseType,
			rc.source.ReleaseType,
		)
	}

	releases, err := rc.pivnet.ReleasesForProductSlug(rc.productSlug)
	if err != nil {
		return pivnet.Release{}, err
	}

	for _, r := range releases {
		if r.Version == version {
			rc.logger.Info(fmt.Sprintf(
				"Deleting existing release: '%s' - id: '%d'",
				r.Version,
				r.ID,
			))

			err := rc.pivnet.DeleteRelease(rc.productSlug, r)
			if err != nil {
				return pivnet.Release{}, err
			}
		}
	}

	config := pivnet.CreateReleaseConfig{
		ProductSlug:           rc.productSlug,
		ReleaseType:           string(releaseType),
		EULASlug:              eulaSlug,
		Version:               version,
		Description:           rc.metadata.Release.Description,
		ReleaseNotesURL:       rc.metadata.Release.ReleaseNotesURL,
		ReleaseDate:           rc.metadata.Release.ReleaseDate,
		Controlled:            rc.metadata.Release.Controlled,
		ECCN:                  rc.metadata.Release.ECCN,
		LicenseException:      rc.metadata.Release.LicenseException,
		EndOfSupportDate:      rc.metadata.Release.EndOfSupportDate,
		EndOfGuidanceDate:     rc.metadata.Release.EndOfGuidanceDate,
		EndOfAvailabilityDate: rc.metadata.Release.EndOfAvailabilityDate,
	}

	rc.logger.Info(fmt.Sprintf("Creating new release with config: %+v", config))
	release, err := rc.pivnet.CreateRelease(config)
	if err != nil {
		return pivnet.Release{}, err
	}

	rc.logger.Info(fmt.Sprintf("Created new release with ID: %d", release.ID))
	return release, nil
}
	"github.com/pivotal-cf/pivnet-resource/metadata"
	"github.com/pivotal-cf/pivnet-resource/versions"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

const (
	executableTimeout = 60 * time.Second
)

var _ = Describe("Out", func() {
	var (
		version string

		releaseType     = pivnet.ReleaseType("Minor Release")
		releaseDate     = "2015-12-17"
		eulaSlug        = "pivotal_beta_eula"
		description     = "this release is for automated-testing only."
		releaseNotesURL = "https://example.com"

		metadataFile = "metadata"

		command         *exec.Cmd
		stdinContents   []byte
		outRequest      concourse.OutRequest
		rootDir         string
		productMetadata metadata.Metadata
	)

	BeforeEach(func() {