def main_build(ctx, # type: click.Context options, # type: Dict[str, Any] all, # type: bool tag, # type: Iterable[str] pip_compile_options, # type: Iterable[str] ): # type: (...) -> None """Build requirements with pip-compile.""" if not options['directory'].exists(): console.error('run `{} init\' first', ctx.find_root().info_name) ctx.abort() if not all and not tag: console.error('either --all or --tag must be provided.') ctx.abort() src_dir = options['directory'] / options['source_dir'] dest_dir = options['directory'] / options['build_dir'] if not dest_dir.exists(): dest_dir.mkdir() default_args = ['-r'] if not tag: pattern = '*{}'.format(options['extension']) tag = (path.stem for path in src_dir.glob(pattern)) for tag_name in tag: src = src_dir / ''.join((tag_name, options['extension'])) dest = dest_dir / '{}.txt'.format(tag_name) console.info('building {}', click.format_filename(str(dest))) args = default_args[:] args += [str(src)] args += list(pip_compile_options) with atomicwrites.AtomicWriter(str(dest), 'w', True).open() as f: f.write(reqwire.scaffold.MODELINES_HEADER) with tempfile.NamedTemporaryFile() as temp_file: args += ['-o', temp_file.name] sh.pip_compile(*args, _out=f, _tty_out=False)
def insert_string_at_line(input_file: str, string_to_be_inserted: str, put_at_line_number: int, output_file: str, append: bool = True, newline_character: str = os.linesep): r"""Write a string at the specified line. :parameter input_file: the file that needs to be read. :parameter string_to_be_inserted: the string that needs to be added. :parameter put_at_line_number: the line number on which to append the string. :parameter output_file: the file that needs to be written with the new content. :parameter append: decides whether to append or prepend the string at the selected line. Defaults to ``True``. :parameter newline_character: set the character used to fill the file in case line_number is greater than the number of lines of input_file. Defaults to the default platform newline, i.e: ``os.linesep``. :type input_file: str :type string_to_be_inserted: str :type line_number: int :type output_file: str :type append: bool :type newline_character: str :returns: None :raises: LineOutOfFileBoundsError or a built-in exception. .. note:: Line numbers start from ``1``. .. note:: Exsisting line endings of the input file are changed to ``newline_character``. """ if put_at_line_number < 1: raise ValueError with open(input_file, 'r') as f: lines = f.readlines() line_counter = 1 i = 0 loop = True extra_lines_done = False line_number_after_eof = len(lines) + 1 # Atomicwrites does not support the newline argument so # all the file writing is done in binary mode. c = atomicwrites.AtomicWriter(output_file, 'w', overwrite=True, newline=newline_character) with c.open() as f: while loop: if put_at_line_number > len( lines) and line_counter == line_number_after_eof: # There are extra lines to write. line = str() else: line = lines[i] # It is ok if the position of line to be written is greater # than the last line number of the input file. We just need to add # the appropriate number of newline characters which will fill # the non existing lines of the output file. if put_at_line_number > len( lines) and line_counter == line_number_after_eof: for additional_newlines in range( 0, put_at_line_number - len(lines) - 1): # Skip the newline in the line where we need to insert # the new string. f.write(newline_character) line_counter += 1 i += 1 extra_lines_done = True if line_counter == put_at_line_number: # A very simple append operation: if the original line ends # with a '\n' character, the string will be added on the next # line... if append: line = line + string_to_be_inserted # ...otherwise the string is prepended. else: line = string_to_be_inserted + line f.write(line) line_counter += 1 i += 1 # Quit the loop if there is nothing more to write. if i >= len(lines): loop = False # Continue looping if there are still extra lines to write. if put_at_line_number > len(lines) and not extra_lines_done: loop = True
def atomic_file_writebytes(b, fn, overwrite=False): with atomicwrites.AtomicWriter(fn, mode='wb', overwrite=overwrite).open() as f: f.write(b)
def _open_writable(path, is_binary): mode = 'wb' if is_binary else 'w' return atomicwrites.AtomicWriter(path, mode=mode, overwrite=True).open()