def _setUp(self): super()._setUp() self.snapcraft_yaml_file_path = os.path.join(self.path, "snap", "snapcraft.yaml") os.makedirs(os.path.join(self.path, "snap"), exist_ok=True) with open(self.snapcraft_yaml_file_path, "w") as snapcraft_yaml_file: yaml_utils.dump(self.data, stream=snapcraft_yaml_file)
def construct_yaml( self, name="test", version="0.1", summary="Simple test snap", description="Something something", grade=None, architectures=None, parts=dedent("""\ my-part: plugin: nil """), build_packages="[]", adopt_info=None, ): snapcraft_yaml = { "name": name, "summary": summary, "description": description, "parts": yaml_utils.load(parts), "build-packages": yaml_utils.load(build_packages), } if version: snapcraft_yaml["version"] = version if adopt_info: snapcraft_yaml["adopt-info"] = adopt_info if grade: snapcraft_yaml["grade"] = grade if architectures: snapcraft_yaml["architectures"] = architectures with open("snapcraft.yaml", "w") as f: yaml_utils.dump(snapcraft_yaml, stream=f)
def set_package_version(self, type_, snapcraft_yaml_path, part, package, version=None): # This doesn't handle complex package syntax. with open(snapcraft_yaml_path) as snapcraft_yaml_file: snapcraft_yaml = yaml_utils.load(snapcraft_yaml_file) if part: packages = snapcraft_yaml["parts"][part].get(type_, []) else: packages = snapcraft_yaml.get(type_, []) for index, package_in_yaml in enumerate(packages): if package_in_yaml.split("=")[0] == package: if version is None: version = get_package_version(package, self.distro_series, self.deb_arch) packages[index] = "{}={}".format(package, version) break else: self.fail("The part {} doesn't have a package {}".format( part, package)) with open(snapcraft_yaml_path, "w") as snapcraft_yaml_file: yaml_utils.dump(snapcraft_yaml, stream=snapcraft_yaml_file) return version
def save(self, **data: Any) -> None: dirpath = os.path.dirname(self._path) if dirpath: os.makedirs(dirpath, exist_ok=True) with open(self._path, "w") as info_file: data.update(dict(self)) yaml_utils.dump(data, stream=info_file)
def extension(name, **kwargs): """Show contents of extension.""" from snapcraft.internal import project_loader dummy_data = lifecycle.get_init_data() extension_instance = project_loader.find_extension(name)(dummy_data) app_snippet = extension_instance.app_snippet part_snippet = extension_instance.part_snippet parts = extension_instance.parts intro = "The {} extension".format(name) if app_snippet: click.echo("{} adds the following to apps that use it:".format(intro)) click.echo(textwrap.indent(yaml_utils.dump(app_snippet), " ")) intro = "It" if part_snippet: click.echo("{} adds the following to all parts:".format(intro)) click.echo(textwrap.indent(yaml_utils.dump(part_snippet), " ")) intro = "It" if parts: click.echo("{} adds the following part definitions:".format(intro)) click.echo(textwrap.indent(yaml_utils.dump(parts), " "))
def expand_extensions(**kwargs): """Display snapcraft.yaml with all extensions applied.""" project = get_project(**kwargs) yaml_with_extensions = project_loader.apply_extensions( project.info.get_raw_snapcraft()) # Loading the config applied all the extensions, so just dump it back out yaml_utils.dump(yaml_with_extensions, stream=sys.stdout)
def define(part_name): try: remote_part = _RemoteParts().get_part(part_name, full=True) except errors.SnapcraftPartMissingError as e: raise errors.PartNotInCacheError(part_name=part_name) from e print("Maintainer: {!r}".format(remote_part.pop("maintainer"))) print("Description: {}".format(remote_part.pop("description"))) print("") yaml_utils.dump({part_name: remote_part}, stream=sys.stdout)
def _save_info(self, *, data: Dict[str, Any]) -> None: filepath = os.path.join(self.provider_project_dir, "project-info.yaml") dirpath = os.path.dirname(filepath) if dirpath: os.makedirs(dirpath, exist_ok=True) with open(filepath, "w") as info_file: yaml_utils.dump(data, stream=info_file)
def test_update_with_changed_date_downloads_again(self): os.makedirs(self.parts_dir) with open(self.headers_yaml, "w") as headers_file: yaml_utils.dump( {"If-Modified-Since": "Fri, 01 Jan 2016 12:00:00 GMT"}, stream=headers_file, ) result = self.run_command(["update"]) self.assertThat(result.exit_code, Equals(0))
def expand_extensions(**kwargs): """Display snapcraft.yaml with all extensions applied.""" if kwargs.get("enable_experimental_extensions"): os.environ["SNAPCRAFT_ENABLE_EXPERIMENTAL_EXTENSIONS"] = "True" project = get_project(**kwargs) yaml_with_extensions = project_loader.apply_extensions( project.info.get_raw_snapcraft()) # Loading the config applied all the extensions, so just dump it back out yaml_utils.dump(yaml_with_extensions, stream=sys.stdout)
def _save_registry(registry_data: Dict[str, List[Any]], registry_filepath: Optional[str]) -> None: if registry_filepath is None: return dirpath = os.path.dirname(registry_filepath) if dirpath: os.makedirs(dirpath, exist_ok=True) with open(registry_filepath, "w") as registry_file: yaml_utils.dump(registry_data, stream=registry_file)
def write_snap_yaml(self, path: str) -> None: """Write snap.yaml contents to specified path.""" snap_dict = self.to_dict() # If the base is core in snapcraft.yaml we do not set it in # snap.yaml LP: #1819290 if self.base == "core": snap_dict.pop("base") with open(path, "w") as f: yaml_utils.dump(snap_dict, stream=f)
def write_snap_yaml(self) -> str: common.env = self._project_config.snap_env() try: package_snap_path = os.path.join(self.meta_dir, "snap.yaml") snap_yaml = self._compose_snap_yaml() with open(package_snap_path, "w") as f: yaml_utils.dump(snap_yaml, stream=f) return snap_yaml finally: common.reset_env()
def add_stage_packages( *, part_name: str, stage_packages: List[str], snapcraft_yaml_file=None ): if snapcraft_yaml_file is None: snapcraft_yaml_file = os.path.join("snap", "snapcraft.yaml") with open(snapcraft_yaml_file) as file_read: y = yaml_utils.load(file_read) if "stage-packages" in y["parts"][part_name]: y["parts"][part_name]["stage-packages"].extend(stage_packages) else: y["parts"][part_name]["stage-packages"] = stage_packages with open(snapcraft_yaml_file, "w") as file_write: yaml_utils.dump(y, stream=file_write)
def _edit_developers(developers: List[Dict[str, str]]) -> List[Dict[str, str]]: """Spawn an editor to modify the snap-developer assertion for a snap.""" editor_cmd = os.getenv("EDITOR", "vi") developer_wrapper = {"developers": developers} with tempfile.NamedTemporaryFile() as ft: ft.close() with open(ft.name, "w") as fw: print(_COLLABORATION_HEADER, file=fw) yaml_utils.dump(developer_wrapper, stream=fw) subprocess.check_call([editor_cmd, ft.name]) with open(ft.name, "r") as fr: developers = yaml_utils.load(fr).get("developers") return developers
def _save_headers(self): headers = { "If-Modified-Since": self._request.headers.get("Last-Modified") } with open(self._headers_yaml, "w") as headers_file: headers_file.write(yaml_utils.dump(headers))
def set_build_package_architecture(self, snapcraft_yaml_path, part, package, architecture): # This doesn't handle complex package syntax. with open(snapcraft_yaml_path) as snapcraft_yaml_file: snapcraft_yaml = yaml_utils.load(snapcraft_yaml_file) packages = snapcraft_yaml["parts"][part]["build-packages"] for index, package_in_yaml in enumerate(packages): if package_in_yaml == package: packages[index] = "{}:{}".format(package, architecture) break else: self.fail("The part {} doesn't have a package {}".format( part, package)) with open(snapcraft_yaml_path, "w") as snapcraft_yaml_file: yaml_utils.dump(snapcraft_yaml, stream=snapcraft_yaml_file)
def generate_meta_yaml( self, *, build=False, actual_prime_dir=None, snapcraft_yaml_file_path=None ): if snapcraft_yaml_file_path is None: snapcraft_yaml_file_path = self.snapcraft_yaml_file_path os.makedirs("snap", exist_ok=True) with open(snapcraft_yaml_file_path, "w") as f: f.write(yaml_utils.dump(self.config_data)) self.project = Project(snapcraft_yaml_file_path=snapcraft_yaml_file_path) if actual_prime_dir is not None: self.project._prime_dir = actual_prime_dir self.meta_dir = os.path.join(self.project.prime_dir, "meta") self.hooks_dir = os.path.join(self.meta_dir, "hooks") self.snap_yaml = os.path.join(self.meta_dir, "snap.yaml") self.config = project_loader.load_config(project=self.project) if build: for part in self.config.parts.all_parts: part.pull() part.build() part.stage() part.prime() _snap_packaging.create_snap_packaging(self.config) self.assertTrue(os.path.exists(self.snap_yaml), "snap.yaml was not created") with open(self.snap_yaml) as f: return yaml_utils.load(f)
def mark_done(self, step, state=None): if not state: state = {} with open(states.get_step_state_file(self.plugin.statedir, step), "w") as f: f.write(yaml_utils.dump(state))
def test_stage_rust_with_source_and_source_subdir(self): self.copy_project_to_cwd("rust-subdir") with open("snapcraft.yaml") as snapcraft_yaml_file: snapcraft_yaml = yaml_utils.load(snapcraft_yaml_file) snapcraft_yaml["parts"]["rust-subdir"]["source"] = "." snapcraft_yaml["parts"]["rust-subdir"]["source-subdir"] = "subdir" with open("snapcraft.yaml", "w") as snapcraft_yaml_file: yaml_utils.dump(snapcraft_yaml, stream=snapcraft_yaml_file) self.run_snapcraft("pull") self.assertThat( os.path.join("parts", "rust-subdir", "src", "subdir", "Cargo.lock"), FileExists(), )
def write_snap_yaml(self) -> str: common.env = self._project_config.snap_env() try: # Only generate the meta command chain if there are apps that need it if self._config_data.get("apps", None): self._generate_command_chain() package_snap_path = os.path.join(self.meta_dir, "snap.yaml") snap_yaml = self._compose_snap_yaml() with open(package_snap_path, "w") as f: yaml_utils.dump(snap_yaml, stream=f) return snap_yaml finally: common.reset_env()
def _record_manifest_and_source_snapcraft_yaml(self): prime_snap_dir = os.path.join(self._prime_dir, "snap") recorded_snapcraft_yaml_path = os.path.join(prime_snap_dir, "snapcraft.yaml") if os.path.isfile(recorded_snapcraft_yaml_path): os.unlink(recorded_snapcraft_yaml_path) manifest_file_path = os.path.join(prime_snap_dir, "manifest.yaml") if os.path.isfile(manifest_file_path): os.unlink(manifest_file_path) # FIXME hide this functionality behind a feature flag for now if os.environ.get("SNAPCRAFT_BUILD_INFO"): os.makedirs(prime_snap_dir, exist_ok=True) shutil.copy2(self._snapcraft_yaml_path, recorded_snapcraft_yaml_path) annotated_snapcraft = _manifest.annotate_snapcraft( self._project_config.project, copy.deepcopy(self._config_data) ) with open(manifest_file_path, "w") as manifest_file: yaml_utils.dump(annotated_snapcraft, stream=manifest_file)
def enable(project): series = storeapi.constants.DEFAULT_SERIES project_config = project_loader.load_config(project) snap_name = project_config.data["name"] logger.info("Enabling Travis testbeds to push and release {!r} snaps " "to edge channel in series {!r}".format(snap_name, series)) packages = [{"name": snap_name, "series": series}] channels = ["edge"] _acquire_and_encrypt_credentials(packages, channels) logger.info( 'Configuring "deploy" phase to build and release the snap in the ' "Store.") with open(TRAVIS_CONFIG_FILENAME, "r+") as fd: travis_conf = yaml_utils.load(fd) # Enable 'sudo' capability and 'docker' service. travis_conf["sudo"] = "required" services = travis_conf.setdefault("services", []) if "docker" not in services: services.append("docker") # Add a 'deploy' section with 'script' provider for building and # release the snap within a xenial docker container. travis_conf["deploy"] = { "skip_cleanup": True, "provider": "script", "script": ("docker run -v $(pwd):$(pwd) -t snapcore/snapcraft sh -c " '"apt update -qq && cd $(pwd) && ' 'snapcraft && snapcraft push *.snap --release edge"'), "on": { "branch": "master" }, } fd.seek(0) yaml_utils.dump(travis_conf, stream=fd) logger.info("Done. Now you just have to review and commit changes in your " "Travis project (`{}`).\n" "Also make sure you add the new `{}` file.".format( TRAVIS_CONFIG_FILENAME, ENCRYPTED_CONFIG_FILENAME))
def test_ordereddict_yaml(self): from collections import OrderedDict data = OrderedDict() data["name"] = "test" data["description"] = "description" output = yaml_utils.dump(data) self.assertTrue(isinstance(yaml_utils.load(output), OrderedDict))
def test_yaml_conversion(self, init_spy): state_string = yaml_utils.dump(self.state) # Verify that the dumped tag was correct self.assertThat(state_string.splitlines()[0], Equals("!BuildState")) # Now verify the conversion state_from_yaml = yaml_utils.load(state_string) self.assertThat(state_from_yaml, Equals(self.state)) # Verify that init was not called init_spy.assert_not_called()
def prepare_repository(self) -> str: """Prepare source tree for launchpad build. Returns repo directory.""" # Copy project assets. self._copy_assets() # Create sources directory for source archives. os.makedirs(self._repo_sources_dir, exist_ok=True) # Process each part with sources. for part_name, part_config in self._snapcraft_config["parts"].items(): part_config = self._process_part_sources(part_name, part_config) self._prepared_snapcraft_config["parts"][part_name] = part_config # Set version. self._set_prepared_project_version() # Write updated snapcraft yaml config. snapcraft_yaml_path = os.path.join(self._repo_snap_dir, "snapcraft.yaml") with open(snapcraft_yaml_path, "w") as f: yaml_utils.dump(self._prepared_snapcraft_config, stream=f) return self._repo_dir
def edit_validation_sets(account_id: str, set_name: str, sequence: int, key_name: str): """Edit the list of validations for <set-name>. Refer to https://snapcraft.io/docs/validation-sets for further information on Validation Sets. """ store_client = StoreClientCLI() asserted_validation_sets = store_client.get_validation_sets( name=set_name, sequence=str(sequence)) try: # assertions should only have one item since a specific # sequence was requested. revision = asserted_validation_sets.assertions[0].revision snaps = yaml_utils.dump({ "snaps": [ s.marshal() for s in asserted_validation_sets.assertions[0].snaps ] }) except IndexError: # If there is no assertion for a given sequence, the store API # will return an empty list. revision = "0" snaps = _VALIDATIONS_SETS_SNAPS_TEMPLATE unverified_validation_sets = _VALIDATION_SETS_TEMPLATE.format( account_id=account_id, set_name=set_name, sequence=sequence, revision=revision, snaps=snaps, ) edited_validation_sets = _edit_validation_sets(unverified_validation_sets) if edited_validation_sets == yaml_utils.load(unverified_validation_sets): echo.warning("No changes made.") else: build_assertion = store_client.post_validation_sets_build_assertion( validation_sets=edited_validation_sets) signed_validation_sets = _sign_assertion(build_assertion.marshal(), key_name=key_name) store_client.post_validation_sets( signed_validation_sets=signed_validation_sets)
def do_GET(self): logger.debug("Handling getting parts") if "If-Modified-Since" in self.headers: ims_date = datetime.strptime(self.headers["If-Modified-Since"], self._date_format) else: ims_date = None if ims_date is not None and ims_date >= self._parts_date: self.send_response(304) response = {} elif "CUSTOM_PARTS" in os.environ: self.send_response(200) response = OrderedDict((( "curl-custom", OrderedDict(( ("plugin", "autotools"), ("source", "http://curl.org"), ("description", "custom curl part"), ("maintainer", "none"), )), ), )) else: self.send_response(200) response = OrderedDict(( ( "curl", OrderedDict(( ("plugin", "autotools"), ("source", "http://curl.org"), ("description", "test entry for curl"), ("maintainer", "none"), )), ), ( "part1", OrderedDict(( ("plugin", "go"), ("source", "http://source.tar.gz"), ("description", "test entry for part1"), ("maintainer", "none"), )), ), ( "long-described-part", OrderedDict(( ("plugin", "go"), ("source", "http://source.tar.gz"), ( "description", "this is a repetitive description " * 3, ), ("maintainer", "none"), )), ), ( "multiline-part", OrderedDict(( ("plugin", "go"), ("source", "http://source.tar.gz"), ( "description", "this is a multiline description\n" * 3, ), ("maintainer", "none"), )), ), )) self.send_header("Content-Type", "text/plain") if "NO_CONTENT_LENGTH" not in os.environ: self.send_header("Content-Length", "1000") self.send_header("Last-Modified", self._parts_date.strftime(self._date_format)) self.send_header("ETag", "1111") self.end_headers() self.wfile.write(yaml_utils.dump(response).encode())
def write_snap_yaml(self, path: str) -> None: """Write snap.yaml contents to specified path.""" snap_dict = self.to_snap_yaml_dict() with open(path, "w") as f: yaml_utils.dump(snap_dict, stream=f, sort_keys=False)
def test_octint_dump(self): output = io.StringIO() yaml_utils.dump(dict(number=yaml_utils.OctInt(8)), stream=output) output.seek(0) self.assertThat(output.read().strip(), Equals("number: 0010"))