code: func syncPrjs(c context.Context, prjs []*projects.Config) error {
  	// Fetch existing configs.
  	srv := getProjServer(c)
  	rsp, err := srv.List(c, &projects.ListRequest{})
  	if err != nil {
  		return errors.Annotate(err, "failed to fetch project configs").Err()
  	}
  	// Track the revision of each config.
  	revs := make(map[string]string, len(rsp.Projects))
  	for _, p := range rsp.Projects {
  		revs[p.Project] = p.Revision
  	}
  	logging.Debugf(c, "fetched %d project configs", len(rsp.Projects))
  
  	// Update configs to new revisions.
  	ens := &projects.EnsureRequest{}
  	for _, p := range prjs {
  		rev, ok := revs[p.Project]
  		delete(revs, p.Project)
  		if ok && rev == p.Revision {
  			continue
  		}
  		ens.Id = p.Project
  		ens.Project = p
  		if _, err := srv.Ensure(c, ens); err != nil {
  			return errors.Annotate(err, "failed to ensure project config %q", ens.Id).Err()
  		}
  	}
  
  	// Delete unreferenced configs.
  	del := &projects.DeleteRequest{}
  	for id := range revs {
  		del.Id = id
  		if _, err := srv.Delete(c, del); err != nil {
  			return errors.Annotate(err, "failed to delete project config %q", del.Id).Err()
  		}
  		logging.Debugf(c, "deleted project config %q", del.Id)
  	}
  	return nil
  }
docs: // syncPrjs synchronizes the given validated project configs.