示例#1
0
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
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
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)
示例#6
0
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)
示例#7
0
    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)
示例#8
0
    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)
示例#9
0
    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)
示例#10
0
def write_dependencies(dependencies):
    json_dump(dependencies, get_dependencies_filename())
示例#11
0
    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)
示例#12
0
    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)
示例#13
0
def write_dependencies(dependencies):
    json_dump(dependencies, get_dependencies_filename())
示例#14
0
    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)