def create_placeholder(path_to_package_json): metadata = json_load(path_to_package_json) # Verify that this represents a Node package. nuclide = metadata.get('nuclide', None) if not isinstance(nuclide, dict): return False if nuclide.get('packageType', None) != 'Node': return False # Verfy that the package has a description. if not metadata.get('description', None): print('package.json must include a description: %s' % path_to_package_json) return False # Verify that the npm user is "fb". npm_user = fs.cross_platform_check_output(['npm', 'whoami']).rstrip() if npm_user != 'fb': print(('You must be the "fb" user to publish a Nuclide package to npm, but you were "%s". ' + 'Find someone who has the appropriate credentials to do the publish for you.') % npm_user) return False # Write out the package.json to a temp directory. tmp_dir = tempfile.mkdtemp('npm-publish') tmp_package_json = os.path.join(tmp_dir, 'package.json') json_dump(metadata, tmp_package_json) # Run `npm publish`. subprocess.check_call(['npm', 'publish'], cwd=tmp_dir) return True
def prepublish(self, new_version, atom_semver): logging.info('Publishing %s to npm at version %s', self.get_package_name(), new_version) # Create temporary directory and copy package into it (without dependencies). package = self._config.package_directory logging.info('Copying %s to tmpdir', self.get_package_name()) shutil.copytree(package, self._tmp_package, ignore=shutil.ignore_patterns('node_modules')) # Make sure that standard boilerplate files are included in the repo. for name, src in self._boilerplate_files.items(): shutil.copyfile( src, os.path.join(self._tmp_package, name)) # Load package.json and rewrite version number within it. package_file = os.path.join(self._tmp_package, 'package.json') package = json_load(package_file) package = update_package_json_versions(self.get_package_name(), package, self._config.nuclide_npm_package_names, new_version) # Specify the license if it is not already specified. if 'license' not in package: package['license'] = 'SEE LICENSE IN LICENSE' # Write the adjusted package file back to the temporary directory and publish it. json_dump(package, package_file) # Pre-transpile Babel files, as appropriate. self._transpiler.transpile_in_place(self.get_package_name(), self._tmp_package) rewrite_shrinkwrap_file(self._tmp_package, package, self._config.nuclide_npm_package_names, new_version)
def prepublish(self, new_version, atom_semver): logging.info('Publishing %s to npm at version %s', self.get_package_name(), new_version) # Create temporary directory and copy package into it (without dependencies). package = self._config.package_directory tmp_package = os.path.join(self._tmpdir, self.get_package_name()) logging.info('Copying %s to tmpdir', self.get_package_name()) shutil.copytree(package, tmp_package, ignore=shutil.ignore_patterns('node_modules')) # Load package.json and rewrite version number within it. nil_semver = '0.0.0' new_semver = '0.0.%d' % new_version package_file = os.path.join(tmp_package, 'package.json') package = json_load(package_file) if package['version'] != nil_semver: raise AssertionError('Local package %s was not at version 0' % self.get_package_name()) package['version'] = new_semver # Update the versions of our local dependencies accordingly. for dependency_key in DEPENDENCIES_KEYS: if not dependency_key in package: continue for (dependency, version) in package[dependency_key].items(): if not self._config.is_nuclide_npm_package(dependency): continue if version != nil_semver: raise AssertionError('Local dependency %s in package %s was not at version 0' % dependency, self.get_package_name()) package[dependency_key][dependency] = new_semver # Write the adjusted package file back to the temporary directory and publish it. json_dump(package, package_file)
def create_placeholder(path_to_package_json, apm_repository_helper): metadata = json_load(path_to_package_json) # Verify that this represents an Atom package. nuclide = metadata.get('nuclide', None) if not isinstance(nuclide, dict): return False if nuclide.get('packageType', None) != 'Atom' or nuclide.get('testRunner', None) != 'apm': return False # Create or checkout the repo for the package under facebooknuclideapm. package_name = metadata['name'] repo = tempfile.mkdtemp(package_name) apm_repository_helper.checkout_apm_repo(package_name, repo, create_if_missing=True) git = apm_repository_helper.git # Verify the package.json file has been checked in. Commit it if it has not. package_json_in_repo = os.path.join(repo, 'package.json') if not os.path.isfile(package_json_in_repo): metadata['repository'] = 'https://github.com/facebooknuclideapm/%s' % package_name json_dump(metadata, package_json_in_repo) git.commit_all(repo, 'Commit package.json file.') git.push_to_master(repo) # Verify the README.md has been checked in. Commit it if it has not. path_to_readme = os.path.join(repo, 'README.md') if not os.path.isfile(path_to_readme): with open(path_to_readme, 'w') as f: f.write('Placeholder.') git.commit_all(repo, 'Commit README.md file.') git.push_to_master(repo) # Create and push tag v0.0.0. tag_name = 'v0.0.0' tag_exists = False try: git.add_tag(repo, tag_name, 'Atom package %s.' % tag_name) except subprocess.CalledProcessError: tag_exists = True if not tag_exists: git.push_tag(repo, tag_name) git.push_to_master(repo) # Run `apm publish` to claim the namespace. try: subprocess.check_call(['apm', 'publish', '--tag', tag_name], cwd=repo) except subprocess.CalledProcessError: # `apm publish` may complain about some things, but at a minimum, the namespace should be # claimed. pass # Verify whether the publish succeeded. try: subprocess.check_call(['apm', 'view', package_name], cwd=repo) return True except subprocess.CalledProcessError: return False
def rewrite_shrinkwrap_file(package_dir, package_name, dependent_packages, new_version): shrinkwrap_file = os.path.join(package_dir, 'npm-shrinkwrap.json') # TODO(peterhal): Remove this test once we have shrinkwraps in place for all packages if os.path.isfile(shrinkwrap_file): shrinkwrap = json_load(shrinkwrap_file) shrinkwrap = update_shrinkwrap_json_versions(package_name, shrinkwrap, dependent_packages, new_version) # Write the adjusted shrinkwrap file back to the temporary directory and publish it. json_dump(shrinkwrap, shrinkwrap_file)
def prepublish(self, new_version, atom_semver): logging.info('Publishing %s to npm at version %s', self.get_package_name(), new_version) # Create temporary directory and copy package into it (without dependencies). package = self._config.package_directory logging.info('Copying %s to tmpdir', self.get_package_name()) shutil.copytree(package, self._tmp_package, ignore=shutil.ignore_patterns('node_modules')) # Make sure that standard boilerplate files are included in the repo. for name, src in self._boilerplate_files.items(): shutil.copyfile(src, os.path.join(self._tmp_package, name)) # Load package.json and rewrite version number within it. package_file = os.path.join(self._tmp_package, 'package.json') package = json_load(package_file) package = update_package_json_versions( self.get_package_name(), package, self._config.nuclide_npm_package_names, new_version) # Delete "_atomModuleCache" field from package.json. # TODO (chenshen): delete following line once '_atomModuleCache' is not fake. if '_atomModuleCache' in package: del package['_atomModuleCache'] # Specify the license if it is not already specified. if 'license' not in package: package['license'] = 'SEE LICENSE IN LICENSE' # Write the adjusted package file back to the temporary directory and publish it. json_dump(package, package_file) # Pre-transpile Babel files, as appropriate. self._transpiler.transpile_in_place(self.get_package_name(), self._tmp_package) rewrite_shrinkwrap_file(self._tmp_package, package, self._config.nuclide_npm_package_names, new_version)
def prepublish(self, new_version, atom_semver): logging.info('Publishing %s to npm at version %s', self.get_package_name(), new_version) # Create temporary directory and copy package into it (without dependencies). package = self._config.package_directory logging.info('Copying %s to tmpdir', self.get_package_name()) shutil.copytree(package, self._tmp_package, ignore=shutil.ignore_patterns('node_modules')) # Make sure that standard boilerplate files are included in the repo. for name, src in self._boilerplate_files.items(): shutil.copyfile(src, os.path.join(self._tmp_package, name)) # Load package.json and rewrite version number within it. nil_semver = '0.0.0' new_semver = '0.0.%d' % new_version package_file = os.path.join(self._tmp_package, 'package.json') package = json_load(package_file) if package['version'] != nil_semver: raise AssertionError('Local package %s was not at version 0' % self.get_package_name()) package['version'] = new_semver # Update the versions of our local dependencies accordingly. for dependency_key in DEPENDENCIES_KEYS: if not dependency_key in package: continue for (dependency, version) in package[dependency_key].items(): if not self._config.is_nuclide_npm_package(dependency): continue if version != nil_semver: raise AssertionError( 'Local dependency %s in package %s was not at version 0' % dependency, self.get_package_name()) package[dependency_key][dependency] = new_semver # Write the adjusted package file back to the temporary directory and publish it. json_dump(package, package_file)
def prepublish(self, new_version, atom_semver): self._repo = self._checkout_apm_repo() logging.info('Publishing %s to apm at version %s', self.get_package_name(), new_version) # Clean repo out, leaving .git metadata in place. logging.info('Cleaning repo for package %s', self.get_package_name()) self.clean_repo() # Copy files from package into repo. package = self._config.package_directory logging.info('Copying package %s', self.get_package_name()) self.copy_into_repo(package) # Load package.json and rewrite version number within it. # TODO (jpearce): reconcile with very similar npm code nil_semver = '0.0.0' new_semver = '0.0.%d' % new_version package_file = os.path.join(self._repo, 'package.json') package = json_load(package_file) if package['version'] != nil_semver: raise AssertionError('Local package %s was not at version 0' % self.get_package_name()) package['version'] = new_semver # Update the versions of our local dependencies accordingly. for dependency_key in DEPENDENCIES_KEYS: if not dependency_key in package: continue for (dependency, version) in package[dependency_key].items(): if not self._config.is_nuclide_npm_package(dependency): continue if version != nil_semver: raise AssertionError( 'Local dependency %s in package %s was not at version 0' % dependency, self.get_package_name()) package[dependency_key][dependency] = new_semver # Update the version of the Atom engine required. package['engines'] = {'atom': '>=%s' % atom_semver} # Rewrite the repository URL. repository = 'https://github.com/facebooknuclideapm/%s' % self.get_package_name( ) package['repository'] = repository # Write the adjusted package file back to the temporary directory and publish it. json_dump(package, package_file) # Add a boilerplate .gitignore file if the package does not already have one. path_to_gitignore = os.path.join(self._repo, '.gitignore') if not os.path.exists(path_to_gitignore): with open(path_to_gitignore, 'w') as f: f.write(DEFAULT_GITIGNORE) # Prefix the README.md with information about the proper repository. path_to_readme = os.path.join(self._repo, 'README.md') if os.path.exists(path_to_readme): with open(path_to_readme, 'r') as f: readme_contents = README_PREFIX + f.read() else: readme_contents = README_PREFIX with open(path_to_readme, 'w') as f: f.write(readme_contents) # Write out the packages to install for the nuclide-installer package. if self.get_package_name() == 'nuclide-installer': from publishers.nuclide_installer_config import generate_config installer_config_json = generate_config( new_semver, self._config.apm_package_names) with open(os.path.join(self._repo, 'lib', 'config.json'), 'w') as f: f.write(installer_config_json) # Now that all of the local changes have been written, commit them. tag_name = 'v' + new_semver self._git.commit_all( self._repo, 'Committing changes in preparation for publishing %s' % tag_name) self._git.add_tag(self._repo, tag_name, 'Atom package %s.' % tag_name) # We commit the tag first because we should fail if the tag has already been pushed. self._git.push_tag(self._repo, tag_name) # Pushing to master is not strictly necessary, but it makes it easier to audit the changes # that have been made between versions over time. self._git.push_to_master(self._repo)
def write_dependencies(dependencies): json_dump(dependencies, get_dependencies_filename())
def prepublish(self, new_version, atom_semver): self._repo = self._checkout_apm_repo() logging.info('Publishing %s to apm at version %s', self.get_package_name(), new_version) # Clean repo out, leaving .git metadata in place. logging.info('Cleaning repo for package %s', self.get_package_name()) self.clean_repo() # Copy files from package into repo. package = self._config.package_directory logging.info('Copying package %s', self.get_package_name()) self.copy_into_repo(package) # Make sure that standard boilerplate files are included in the repo. for name, src in self._boilerplate_files.items(): shutil.copyfile(src, os.path.join(self._repo, name)) # Load package.json and rewrite version number within it. package_file = os.path.join(self._repo, 'package.json') package = json_load(package_file) package = update_package_json_versions( self.get_package_name(), package, self._config.nuclide_npm_package_names, new_version) # Specify the license if it is not already specified. if 'license' not in package: package['license'] = 'SEE LICENSE IN LICENSE' # Update the version of the Atom engine required. package['engines'] = {'atom': '>=%s' % atom_semver} # Rewrite the repository URL. repository = 'https://github.com/facebooknuclideapm/%s' % self.get_package_name( ) package['repository'] = repository # Write the adjusted package file back to the temporary directory and publish it. json_dump(package, package_file) rewrite_shrinkwrap_file(self._repo, package, self._config.nuclide_npm_package_names, new_version) # Add a boilerplate .gitignore file if the package does not already have one. path_to_gitignore = os.path.join(self._repo, '.gitignore') if not os.path.exists(path_to_gitignore): with open(path_to_gitignore, 'w') as f: f.write(DEFAULT_GITIGNORE) # Prefix the README.md with information about the proper repository. path_to_readme = os.path.join(self._repo, 'README.md') if os.path.exists(path_to_readme): with open(path_to_readme, 'r') as f: readme_contents = README_PREFIX + f.read() else: readme_contents = README_PREFIX with open(path_to_readme, 'w') as f: f.write(readme_contents) # Write out the packages to install for the nuclide-installer package. if self.get_package_name() == 'nuclide-installer': from publishers.nuclide_installer_config import generate_config installer_config_json = generate_config( package['version'], self._config.apm_package_names) with open(os.path.join(self._repo, 'lib', 'config.json'), 'w') as f: f.write(installer_config_json) # Pre-transpile Babel files, as appropriate. self._transpiler.transpile_in_place(self.get_package_name(), self._repo)
def prepublish(self, new_version, atom_semver): self._repo = self._checkout_apm_repo() logging.info('Publishing %s to apm at version %s', self.get_package_name(), new_version) # Clean repo out, leaving .git metadata in place. logging.info('Cleaning repo for package %s', self.get_package_name()) self.clean_repo() # Copy files from package into repo. package = self._config.package_directory logging.info('Copying package %s', self.get_package_name()) self.copy_into_repo(package) # Make sure that standard boilerplate files are included in the repo. for name, src in self._boilerplate_files.items(): shutil.copyfile( src, os.path.join(self._repo, name)) # Load package.json and rewrite version number within it. package_file = os.path.join(self._repo, 'package.json') package = json_load(package_file) package = update_package_json_versions(self.get_package_name(), package, self._config.nuclide_npm_package_names, new_version) # Specify the license if it is not already specified. if 'license' not in package: package['license'] = 'SEE LICENSE IN LICENSE' # Update the version of the Atom engine required. package['engines'] = {'atom': '>=%s' % atom_semver} # Rewrite the repository URL. repository = 'https://github.com/facebooknuclideapm/%s' % self.get_package_name() package['repository'] = repository # Write the adjusted package file back to the temporary directory and publish it. json_dump(package, package_file) rewrite_shrinkwrap_file(self._repo, package, self._config.nuclide_npm_package_names, new_version) # Add a boilerplate .gitignore file if the package does not already have one. path_to_gitignore = os.path.join(self._repo, '.gitignore') if not os.path.exists(path_to_gitignore): with open(path_to_gitignore, 'w') as f: f.write(DEFAULT_GITIGNORE) # Prefix the README.md with information about the proper repository. path_to_readme = os.path.join(self._repo, 'README.md') if os.path.exists(path_to_readme): with open(path_to_readme, 'r') as f: readme_contents = README_PREFIX + f.read() else: readme_contents = README_PREFIX with open(path_to_readme, 'w') as f: f.write(readme_contents) # Write out the packages to install for the nuclide-installer package. if self.get_package_name() == 'nuclide-installer': from publishers.nuclide_installer_config import generate_config installer_config_json = generate_config(package['version'], self._config.apm_package_names) with open(os.path.join(self._repo, 'lib', 'config.json'), 'w') as f: f.write(installer_config_json) # Pre-transpile Babel files, as appropriate. self._transpiler.transpile_in_place(self.get_package_name(), self._repo)
def prepublish(self, new_version, atom_semver): self._repo = self._checkout_apm_repo() logging.info('Publishing %s to apm at version %s', self.get_package_name(), new_version) # Clean repo out, leaving .git metadata in place. logging.info('Cleaning repo for package %s', self.get_package_name()) self.clean_repo() # Copy files from package into repo. package = self._config.package_directory logging.info('Copying package %s', self.get_package_name()) self.copy_into_repo(package) # Load package.json and rewrite version number within it. # TODO (jpearce): reconcile with very similar npm code nil_semver = '0.0.0' new_semver = '0.0.%d' % new_version package_file = os.path.join(self._repo, 'package.json') package = json_load(package_file) if package['version'] != nil_semver: raise AssertionError('Local package %s was not at version 0' % self.get_package_name()) package['version'] = new_semver # Update the versions of our local dependencies accordingly. for dependency_key in DEPENDENCIES_KEYS: if not dependency_key in package: continue for (dependency, version) in package[dependency_key].items(): if not self._config.is_nuclide_npm_package(dependency): continue if version != nil_semver: raise AssertionError('Local dependency %s in package %s was not at version 0' % dependency, self.get_package_name()) package[dependency_key][dependency] = new_semver # Update the version of the Atom engine required. package['engines'] = {'atom': '>=%s' % atom_semver} # Rewrite the repository URL. repository = 'https://github.com/facebooknuclideapm/%s' % self.get_package_name() package['repository'] = repository # Write the adjusted package file back to the temporary directory and publish it. json_dump(package, package_file) # Add a boilerplate .gitignore file if the package does not already have one. path_to_gitignore = os.path.join(self._repo, '.gitignore') if not os.path.exists(path_to_gitignore): with open(path_to_gitignore, 'w') as f: f.write(DEFAULT_GITIGNORE) # Prefix the README.md with information about the proper repository. path_to_readme = os.path.join(self._repo, 'README.md') if os.path.exists(path_to_readme): with open(path_to_readme, 'r') as f: readme_contents = README_PREFIX + f.read() else: readme_contents = README_PREFIX with open(path_to_readme, 'w') as f: f.write(readme_contents) # Write out the packages to install for the nuclide-installer package. if self.get_package_name() == 'nuclide-installer': from publishers.nuclide_installer_config import generate_config installer_config_json = generate_config(new_semver, self._config.apm_package_names) with open(os.path.join(self._repo, 'lib', 'config.json'), 'w') as f: f.write(installer_config_json) # Now that all of the local changes have been written, commit them. tag_name = 'v' + new_semver self._git.commit_all(self._repo, 'Committing changes in preparation for publishing %s' % tag_name) self._git.add_tag(self._repo, tag_name, 'Atom package %s.' % tag_name) # We commit the tag first because we should fail if the tag has already been pushed. self._git.push_tag(self._repo, tag_name) # Pushing to master is not strictly necessary, but it makes it easier to audit the changes # that have been made between versions over time. self._git.push_to_master(self._repo)